#include "DrawTexture.h"
#include <QOpenGLTexture>
#include <QTimer>
#include <qapplication.h>

static constexpr const char* vertexShaderText =
"#version 330 core\n"
"layout (location = 0) in vec2 textCoord;\n"
"layout (location = 1) in vec4 posAttr;\n"
"out vec2 TextureCoord2;\n"
"void main() {\n"
"   TextureCoord2 = textCoord;\n"
"   gl_Position = posAttr;\n"
"}\n";

static constexpr const char* fragmentShaderText =
"#version 330 core\n"
"in vec2 TextureCoord2;\n"
"uniform sampler2D texture1;\n"
"void main() {\n"
"   gl_FragColor = texture(texture1, TextureCoord2);\n"
"}\n";

DrawTexture::DrawTexture()
{
}

QString DrawTexture::createPluginMenu()
{
	return tr("opengl/drawTexture");
}

void DrawTexture::createPluginMenuResult(bool result, QString menuId, QString error)
{
	// TODO
}

QWidget* DrawTexture::createPluginWidget()
{
	if (m_glWidget == nullptr)
	{
		m_glWidget = new OpenglWidget();
	}
	return m_glWidget;
}

void DrawTexture::destroyPluginWidget()
{
	if (m_glWidget)
	{
		delete m_glWidget;
		m_glWidget = nullptr;
	}
}

GLuint textureId;
QOpenGLTexture* texture;
bool switchTexture = false;
void OpenglWidget::initializeGL()
{
	QVector<QVector3D> vertexData = {
		QVector3D(0 , 1,0),
		QVector3D(-1,-1,0),
		QVector3D(1 ,-1,0),
	};
	QVector<QVector2D> textureData = {
		QVector2D(0.5 , 0),
		QVector2D(0 , 1),
		QVector2D(1 , 1),
	};

	initializeOpenGLFunctions();
	if (!m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderText))
	{
		qDebug() << m_program.log();
		Q_ASSERT(false);
	}
	qDebug() << m_program.log();
	if (!m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderText))
	{
		qDebug() << m_program.log();
		Q_ASSERT(false);
	}
	qDebug() << m_program.log();
	m_program.link();

	int posAttri = m_program.attributeLocation("posAttr");
	int textureCoordAttri = m_program.attributeLocation("textCoord");

	QImage img = QImage(":/1.jpg").convertToFormat(QImage::Format_RGBA8888);
	glGenTextures(1, &textureId);
	glBindTexture(GL_TEXTURE_2D, textureId);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
		img.constBits());
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glEnable(GL_TEXTURE_2D);

	texture = new QOpenGLTexture(QImage(":/2.jpg"));
	texture->setMinificationFilter(QOpenGLTexture::Linear);
	texture->setMagnificationFilter(QOpenGLTexture::Linear);
	texture->setWrapMode(QOpenGLTexture::Repeat);

	GLuint vbo1;
	GLuint vbo2;
	glGenBuffers(1, &vbo1);
	glGenBuffers(1, &vbo2);

	glBindBuffer(GL_ARRAY_BUFFER, vbo1);
	glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexData.size() * 3, vertexData.constData(), GL_STATIC_DRAW);
	m_program.enableAttributeArray(posAttri);
	m_program.setAttributeBuffer(posAttri, GL_FLOAT, 0, 3);

	glBindBuffer(GL_ARRAY_BUFFER, vbo2);
	glBufferData(GL_ARRAY_BUFFER, sizeof(float) * textureData.size() * 2, textureData.constData(), GL_STATIC_DRAW);
	m_program.enableAttributeArray(textureCoordAttri);
	m_program.setAttributeBuffer(textureCoordAttri, GL_FLOAT, 0, 3);

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	m_program.release();
}

void OpenglWidget::resizeGL(int w, int h)
{
	glViewport(0, 0, w, h);
}

void OpenglWidget::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glDisable(GL_DEPTH_TEST);
	
	if (switchTexture)
	{
		glBindTexture(GL_TEXTURE_2D, textureId);
	}
	else
	{
		texture->bind();
	}
	m_program.bind();

	glDrawArrays(GL_TRIANGLES, 0, 3);

	//texture->release();
	m_program.release();
}
